<?php

class ConfigFormBuilder
{
	var $ready = false;
	/**
	 * Список имен параметров, для которых строить форму.
	 * Если форма строиться не для всех парамтеров из конфига.
	 */
	var $params = NULL;

	public function __construct ($config=array(), $init=true)
	{
		foreach ($config as $k=>&$v) $this->$k = $v;
		if ($init) $this->init();
	} // end of __construct
	public function init ($force=false)
	{
		if ($this->ready && !$force) return true; $this->ready = false;

		do {
			$this->ready = true;
		} while (false);

		return $this->ready;
	} // end of method init
	public function build ($cfg)
	{
		// parse file config.php
		$form = array();

		// build form
		$form['type'] = 'form';
		if ($tfile = $cfg->describe()) {
			if ($t = PhpDocUtils::findFirstTagByName('title', $tfile)) {
				$form['title'] = trim($t['value'], '.');
			}
		}

		$keys = $cfg->listParams();
		foreach ($keys as $k => $v) {
			if ($tfield = $cfg->describeParam($k)) {
				// fill form with fields for configurable parameters
				if ($field = $this->buildFormField($tfield)) {
					if (!is_array($this->params) || in_array($field['name'], $this->params)) {
						$form['fields'][$field['name']] = $field;
					}
				}
			}
		}

		// add form buttons
		$form['buttons'] = $this->buildFormButtons($form);

		// если у формы лишь одно поле, установить заголовок формы и описание,
		// как у поля. а в самом поле затереть.
		if (count($form['fields']) === 1) {
			foreach ($form['fields'] as $k=>&$v) {
				$form['title'] = $v['title'];
				$form['description'] = $v['description'];
				$v['title'] = '';
				$v['description'] = NULL;
			}
		}

		return $form;
	} // end of method buildForm

	public function buildFormField (&$doc)
	{
		$res = NULL;
		do {
			$field = array();

			$tname = PhpDocUtils::findFirstTagByName('name', $doc);
			if (!$tname) break;

			$name = $tname['value'];
			if (preg_match('#^\$[[:alnum:]]+\s*\[\s*([\'"]?)(.*?)\1\s*]$#', $name, $ms)) {
				$name = $ms[2];
			}
			$field['name'] = $name;

			$tvar = PhpDocUtils::findFirstTagByName('var', $doc);

			if ($t = PhpDocUtils::findFirstTagByName('type', $doc)) {
				$type = $t['value'];
			} elseif ($tvar) {
				$type = $tvar['type'];
			} else {
				$type = 'mixed';
			}
			switch ($type) {
				case 'boolean':
					$ftype = ucfirst($type); break;
				case 'text':
					$ftype = $type; break;
				case 'password':
					$ftype = $type.'Edit'; break;
				case 'mixed':
				case 'string':
				default:
					$ftype = 'text'; break;
			}
			$field['type'] = $ftype;

			if ($t = PhpDocUtils::findFirstTagByName('title', $doc)) {
				$field['title'] = trim($t['value'], '.');
			}

			if ($t = PhpDocUtils::findFirstTagByName('doc', $doc)) {
				$field['description'] = $t['value'];
			} elseif ($tvar) {
				$field['description'] = $tvar['doc'];
			}

			if ($t = PhpDocUtils::findFirstTagByName('value', $doc)) {
				$field['value'] = PhpDocUtils::extractPhpValue($t['value']);
			}

			if ($t = PhpDocUtils::findFirstTagByName('access', $doc)) {
				if ($t['access'] === 'private') /*don't put this field */break;
				elseif ($t['access'] === 'protected') { $field['readonly'] = true; }
			}
			$res = $field;
		} while (false);
		return $res;
	} // end of method buildFormField
	public function buildFormButtons (&$doc)
	{
		$buttons = array(
			'save' => array(
				'type' => 'image',
				'title' => 'Установить',
				'src' => '../skins/platonica/images/button-save.gif',
			),
		);
		return $buttons;
	} // end of method buildFormButtons
};

